package com.geeksaga.search;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import com.geeksaga.common.util.BundleUtils;

/**
 * @author newbie
 * @since 0.1
 */
public class LuceneEngine {
	private static LuceneEngine instance = new LuceneEngine();
//	private static Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
	private static Analyzer analyzer = new KoreanAnalyzer(Version.LUCENE_CURRENT);
	private Object monitor = new Object();
//	private String indexFolder = null;

	private LuceneEngine() {
	    initialize();
	}
	
	public static LuceneEngine getInstance() {
	    return instance;
	}
 
	public void initialize() {
	    Directory directory = null;
	    IndexWriter indexWriter = null;

		synchronized(monitor) {
			try {			
				directory = FSDirectory.open(new File(BundleUtils.getString("GeekSaga", "INDEX_ROOT")));
				
				if (!directory.fileExists("segments.gen"))
					indexWriter = new IndexWriter(directory, analyzer, true, new IndexWriter.MaxFieldLength(30000));
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
			    if (indexWriter != null) try { indexWriter.close(); } catch (Exception e) { }
			    if (directory != null) try { directory.close(); } catch (Exception e) {}
			}
		}
	}

   public List<String> search(String queryString) {
        Directory directory = null;
        IndexSearcher indexSearcher = null;
        List<String> list = new ArrayList<String>();
        
        try {
            directory = FSDirectory.open(new File(BundleUtils.getString("GeekSaga", "INDEX_ROOT")));
            indexSearcher = new IndexSearcher(directory, true);
            QueryParser parser = new QueryParser("content", analyzer);
            Query query = parser.parse(queryString);
            
            ScoreDoc[] hits = indexSearcher.search(query, null, 1000).scoreDocs;

            for (int i = 0, j = hits.length; i < j; i++) {
                Document document = indexSearcher.doc(hits[i].doc);

                if (!list.contains(document.get("key")))
                    list.add(document.get("key"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (directory != null) try { directory.close(); } catch (Exception exception) {}
            if (indexSearcher != null) try { indexSearcher.close(); } catch (Exception exception) {}
        }
        
        return list;
    }
	   
	public void addDocument(String content, String key) {
	    Directory directory = null;
	    IndexWriter indexWriter = null;
		
		synchronized(monitor) {
			try {
				directory = FSDirectory.open(new File(BundleUtils.getString("GeekSaga", "INDEX_ROOT")));
				
				boolean isLock = IndexWriter.isLocked(directory);
				
				if (isLock)
					IndexWriter.unlock(directory);
				
				indexWriter = new IndexWriter(directory, analyzer, false, new IndexWriter.MaxFieldLength(30000));
				
				Document document = new Document();
				document.add(new Field("key", key, Field.Store.YES, Field.Index.NOT_ANALYZED));
				document.add(new Field("content", content, Field.Store.NO, Field.Index.ANALYZED));
				indexWriter.addDocument(document);
			} catch (Exception e) {
			    e.printStackTrace();
			} finally {
				if (indexWriter != null) try { indexWriter.close(); } catch (Exception e) {}
				if (directory != null) try { directory.close(); } catch (Exception e) {}
			}
		}
	}
	
    public void deleteDocument(String key) {
        Directory directory = null; 
        IndexReader indexReader = null;

        synchronized(monitor) {
            try {
                directory = FSDirectory.open(new File(BundleUtils.getString("GeekSaga", "INDEX_ROOT")));
                indexReader = IndexReader.open(directory, false);
                
                indexReader.deleteDocuments(new Term("key", key));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (indexReader != null) try { indexReader.close(); } catch (Exception e) {}
                if (directory != null) try { directory.close(); } catch (Exception e) {}
            }
        }
    }
}